package com.vcommon.core.modules
{
import com.vcommon.core.loaderqueue.ILoaderAdapter;
import com.vcommon.core.loaderqueue.LoaderQueue;
import com.vcommon.core.loaderqueue.LoaderQueueEvent;
import com.vcommon.core.loaderqueue.adapter.LoaderAdapter;
import com.vcommon.core.logging.Tracer;

import flash.events.EventDispatcher;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.Capabilities;
import flash.system.LoaderContext;
import flash.system.SecurityDomain;
import flash.utils.ByteArray;

/**
 *
 * @author Austin
 *
 */
public class AbstractModuleInfo extends EventDispatcher implements IModuleInfo
{
    //==========================================================================
    //  Constructor
    //==========================================================================
    /**
     * Constructs a new <code>AbstractModuleInfo</code> instance.
     *
     */
    public function AbstractModuleInfo(moduleName:String, skinDir:String)
    {
        super();
        this._moduleName = moduleName;
        moduleVO =
            ModuleManager.getModuleVOByName(moduleName);
        this.skinDir = skinDir;
    }

    //==========================================================================
    //  Variables
    //==========================================================================
    /**
     * 皮肤加载目录
     */
    protected var skinDir:String;

    protected var moduleVO:ModuleVO;
    /**
     * 主swf加载器
     */
    protected var mainLoader:ILoaderAdapter;

    protected var loaderContext:LoaderContext;
    protected var loaderQueue:LoaderQueue = ModuleManager.loaderQueueIns;

    protected var loaderLevel:uint = 0;

    /**
     * 已加载的皮肤数
     */
    protected var skinLoadednum:uint = 0;

    //==========================================================================
    //  Properties
    //==========================================================================
    //----------------------------------
    //  data
    //----------------------------------
    protected var _data:Object;
    /**
     * 加载内容/数据
     */
    public function get data():Object
    {
        return _data;
    }

    public function set data(value:Object):void
    {
        _data = value;
    }

    //----------------------------------
    //  error
    //----------------------------------
    protected var _error:Boolean = false;
    /**
     * 加载错误标记
     */
    public function get error():Boolean
    {
        return _error;
    }

    //----------------------------------
    //  factory
    //----------------------------------
    protected var _factoy:IModuleFactory;
    /**
     * @模块工厂
     */
    public function get factory():IModuleFactory
    {
        return _factoy;
    }

    //----------------------------------
    //  loaded
    //----------------------------------
    protected var _loaded:Boolean = false;
    /**
     * 是否加载过
     */
    public function get loaded():Boolean
    {
        return _loaded;
    }

    //----------------------------------
    //  ready
    //----------------------------------
    protected var _ready:Boolean = false;
    /**
     * 是否加载完毕
     */
    public function get ready():Boolean
    {
        return _ready;
    }

    //----------------------------------
    //  moduleName
    //----------------------------------
    protected var _moduleName:String;
    /**
     * 模块名称
     */
    public function get moduleName():String
    {
        return _moduleName;
    }

    //----------------------------------
    //  applicationDomain
    //----------------------------------
    protected var _applicationDomain:ApplicationDomain;
    /**
     * 加载应用域
     */
    public function get applicationDomain():ApplicationDomain
    {
        return _applicationDomain;
    }

    //==========================================================================
    //  Methods
    //==========================================================================

    public function load(applicationDomain:ApplicationDomain=null,
                         securityDomain:SecurityDomain=null,
                         bytes:ByteArray=null, level:uint=0):void
    {
        if(_ready)
        {
            dispatchEvent(new ModuleEvent(ModuleEvent.READY));
        }
        if(_loaded)
        {
            return;
        }
        _loaded = true;

        loaderContext = new LoaderContext();
        loaderContext.applicationDomain =
            applicationDomain ? applicationDomain :
            new ApplicationDomain(ApplicationDomain.currentDomain);
        if (Capabilities.playerType == "Desktop")
        {
            loaderContext["allowCodeImport"] = true;
            loaderContext["allowLoadBytesCodeExecution"] = true;
        }
    }

    public function unload():void
    {
        clearLoader();
        if (_loaded)
        {
            dispatchEvent(new ModuleEvent(ModuleEvent.UNLOAD));
        }
        _applicationDomain = null;
        _factoy = null;
        _loaded = false;
        _ready = false;
        _error = false;
    }

    /**
     * @private
     */
    protected function clearLoader():void
    {
        if(mainLoader)
        {
            mainLoader.removeEventListener(LoaderQueueEvent.TASK_COMPLETED,
                mainLoader_completedHandler);
            mainLoader.removeEventListener(LoaderQueueEvent.TASK_ERROR,
                mainLoader_errorHandler);
            mainLoader.removeEventListener(LoaderQueueEvent.TASK_PROGRESS,
                mainLoader_progressHandler);
            mainLoader = null;
        }
    }

    /**
     * 开始加载皮肤
     * @param index 指定加载第几个皮肤
     *
     */
    protected function startLoadSkin():void
    {
        if (moduleVO.skinArr.length > 0)
        {
            for each (var url:String in moduleVO.skinArr)
            {
                downloadSkin(url);
            }
        }
        else
        {
            dispatchEvent(new ModuleEvent(ModuleEvent.READY));
        }
    }

    protected function downloadSkin(url:String):void
    {
        var urlRequest:URLRequest = new URLRequest(skinDir+"/"+url);

        var skinLoader:LoaderAdapter = new LoaderAdapter(loaderLevel, urlRequest,
            loaderContext);
        skinLoader.addEventListener(LoaderQueueEvent.TASK_COMPLETED,
            skinLoader_completedHandler);
        skinLoader.addEventListener(LoaderQueueEvent.TASK_ERROR,
            skinLoader_errorHandler);
        skinLoader.addEventListener(LoaderQueueEvent.TASK_PROGRESS,
            skinLoader_progressHandler);
        Tracer.debug("[Module] loading skin: " + skinLoader.url);
        loaderQueue.addItem(skinLoader);
    }

    /**
     * 移除所有皮肤加载器的侦听事件
     */
    protected function removeAllSkinListener(target:EventDispatcher):void
    {
        target.removeEventListener(LoaderQueueEvent.TASK_COMPLETED,
            skinLoader_completedHandler);
        target.removeEventListener(LoaderQueueEvent.TASK_ERROR,
            skinLoader_errorHandler);
        target.removeEventListener(LoaderQueueEvent.TASK_PROGRESS,
            skinLoader_progressHandler);
    }

    //==========================================================================
    //  Event Handlers
    //==========================================================================

    /**
     * 主程序swf加载完成后触发
     * @param event
     *
     */
    protected function mainLoader_completedHandler(event:LoaderQueueEvent):void
    {
        throw(new Error("方法必须由子类实现:mainLoader_completedHandler()"))
    }

    protected function mainLoader_progressHandler(event:LoaderQueueEvent):void
    {
        var moduleEvent:ModuleEvent = new ModuleEvent(ModuleEvent.PROGRESS);
        moduleEvent.bytesLoaded = event.bytesLoaded;
        moduleEvent.bytesTotal = event.bytesTotal;
        dispatchEvent(moduleEvent);
    }

    /**
     * 主程序swf加载出错后触发
     * @param event
     *
     */
    protected function mainLoader_errorHandler(event:LoaderQueueEvent):void
    {
        _error = true;
        Tracer.error("[Module Error] " + event.toString());
        var moduleEvent:ModuleEvent = new ModuleEvent(ModuleEvent.ERROR);
        moduleEvent.errorText = event.toString();
        dispatchEvent(moduleEvent);
    }

    /**
     * 单个皮肤加载完成后触发
     * @param event
     */
    protected function skinLoader_completedHandler(event:LoaderQueueEvent):void
    {
        skinLoadednum++
        removeAllSkinListener(event.currentTarget as EventDispatcher);
        if (skinLoadednum == moduleVO.skinArr.length)
        {
            dispatchEvent(new ModuleEvent(ModuleEvent.READY));
        }
    }

    /**
     * 单个皮肤加载出错后触发
     * @param event
     */
    protected function skinLoader_errorHandler(event:LoaderQueueEvent):void
    {
        Tracer.error("[Module Skin Error] " + ILoaderAdapter(event.currentTarget).url);
        removeAllSkinListener(event.currentTarget as EventDispatcher);
        _error = true;
        var moduleEvent:ModuleEvent = new ModuleEvent(ModuleEvent.ERROR);
        moduleEvent.errorText = event.toString();
        dispatchEvent(moduleEvent);
    }

    protected function skinLoader_progressHandler(event:LoaderQueueEvent):void
    {
        var moduleEvent:ModuleEvent = new ModuleEvent(ModuleEvent.PROGRESS);
        moduleEvent.bytesLoaded = event.bytesLoaded;
        moduleEvent.bytesTotal = event.bytesTotal;
        dispatchEvent(moduleEvent);
    }

}
}